/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/
package com.genia.toolbox.basics.manager.impl;

import java.io.File;
import java.io.IOException;

import com.genia.toolbox.basics.exception.technical.TechnicalIOException;
import com.genia.toolbox.basics.manager.ExceptionManager;
import com.genia.toolbox.basics.manager.FileManager;

/**
 * implementation of {@link FileManager}.
 */
public class FileManagerImpl
    implements FileManager
{

  /**
   * the {@link File} to delete once the application is shutdown.
   */
  private static File rootTemporaryDirectory = null;

  /**
   * Adding a shutdown thread.
   */
  static {
    Runtime.getRuntime().addShutdownHook(new Thread()
    {
      /**
       * the method called when the JVM is shutdown.
       * 
       * @see java.lang.Thread#run()
       */
      @Override
      public void run()
      {
        if (rootTemporaryDirectory != null) {
          staticDeleteRecursively(rootTemporaryDirectory);
        }
      }
    });

  }



  /**
   * delete the given file as well as its children.
   * 
   * @param root
   *          the root of the files to delete
   * @see com.genia.toolbox.basics.manager.FileManager#deleteRecursively(java.io.File)
   */
  private static void staticDeleteRecursively(File root)
  {
    if (root == null || !root.exists()) {
      return;
    }
    if (root.isDirectory()) {
      for (File child : root.listFiles()) {
        staticDeleteRecursively(child);
      }
    }
    root.delete();
  }

  /**
   * the {@link ExceptionManager} to use.
   */
  private ExceptionManager exceptionManager;



  /**
   * Creates an empty directory in the default temporary-file directory, using
   * the given prefix and suffix to generate its name. This directory will be
   * deleted when the JVM shutdown.
   * 
   * @param prefix
   *          The prefix string to be used in generating the file's name; must
   *          be at least three characters long
   * @param suffix
   *          The suffix string to be used in generating the file's name; may be
   *          <code>null</code>, in which case the suffix <code>".tmp"</code>
   *          will be used
   * @return An abstract pathname denoting a newly-created empty directory
   * @throws TechnicalIOException
   *           when an error occured
   * @see File#createTempFile(String, String)
   * @see com.genia.toolbox.basics.manager.FileManager#createAutoDeletableTempDirectory(String,
   *      String)
   */
  public File createAutoDeletableTempDirectory(final String prefix, final String suffix)
      throws TechnicalIOException
  {
    if (rootTemporaryDirectory == null) {
      rootTemporaryDirectory = createTempDirectory("deletableDirectory", ".dir");
    }
    return createTempDirectory(prefix, suffix, rootTemporaryDirectory);
  }



  /**
   * Creates an empty file in the default temporary-file directory, using the
   * given prefix and suffix to generate its name. This file will be deleted
   * when the JVM shutdown.
   * 
   * @param prefix
   *          The prefix string to be used in generating the file's name; must
   *          be at least three characters long
   * @param suffix
   *          The suffix string to be used in generating the file's name; may be
   *          <code>null</code>, in which case the suffix <code>".tmp"</code>
   *          will be used
   * @return An abstract pathname denoting a newly-created empty directory
   * @throws TechnicalIOException
   *           when an error occured
   * @see File#createTempFile(String, String)
   * @see com.genia.toolbox.basics.manager.FileManager#createAutoDeletableTempFile(String,
   *      String)
   */
  public File createAutoDeletableTempFile(final String prefix, final String suffix)
      throws TechnicalIOException
  {
    if (rootTemporaryDirectory == null) {
      rootTemporaryDirectory = createTempDirectory("deletableDirectory", ".dir");
    }
    return createTempFile(prefix, suffix, rootTemporaryDirectory);
  }



  /**
   * Creates an empty directory in the default temporary-file directory, using
   * the given prefix and suffix to generate its name.
   * 
   * @param prefix
   *          The prefix string to be used in generating the file's name; must
   *          be at least three characters long
   * @param suffix
   *          The suffix string to be used in generating the file's name; may be
   *          <code>null</code>, in which case the suffix <code>".tmp"</code>
   *          will be used
   * @return An abstract pathname denoting a newly-created empty directory
   * @throws TechnicalIOException
   *           when an error occured
   * @see File#createTempFile(String, String)
   * @see com.genia.toolbox.basics.manager.FileManager#createTempDirectory(java.lang.String,
   *      java.lang.String)
   */
  public File createTempDirectory(String prefix, String suffix)
      throws TechnicalIOException
  {
    return createTempDirectory(prefix, suffix, null);
  }



  /**
   * Creates an empty directory in the default temporary-file directory, using
   * the given prefix and suffix to generate its name.
   * 
   * @param prefix
   *          The prefix string to be used in generating the file's name; must
   *          be at least three characters long
   * @param suffix
   *          The suffix string to be used in generating the file's name; may be
   *          <code>null</code>, in which case the suffix <code>".tmp"</code>
   *          will be used
   * @param rootDirectory
   *          The directory in which the file is to be created, or
   *          <code>null</code> if the default temporary-file directory is to
   *          be used
   * @return An abstract pathname denoting a newly-created empty directory
   * @throws TechnicalIOException
   *           when an error occured
   * @see File#createTempFile(String, String)
   * @see com.genia.toolbox.basics.manager.FileManager#createTempDirectory(String,
   *      String, File)
   */
  public File createTempDirectory(String prefix, String suffix, File rootDirectory)
      throws TechnicalIOException
  {
    File tempDirectory = createTempFile(prefix, suffix, rootDirectory);
    tempDirectory.delete();
    tempDirectory.mkdirs();
    return tempDirectory;
  }



  /**
   * delete the given file as well as its children.
   * 
   * @param root
   *          the root of the files to delete
   * @see com.genia.toolbox.basics.manager.FileManager#deleteRecursively(java.io.File)
   */
  public void deleteRecursively(File root)
  {
    staticDeleteRecursively(root);
  }



  /**
   * getter for the exceptionManager property.
   * 
   * @return the exceptionManager
   */
  public ExceptionManager getExceptionManager()
  {
    return exceptionManager;
  }



  /**
   * setter for the exceptionManager property.
   * 
   * @param exceptionManager
   *          the exceptionManager to set
   */
  public void setExceptionManager(ExceptionManager exceptionManager)
  {
    this.exceptionManager = exceptionManager;
  }



  /**
   * Creates an empty file in the default temporary-file directory, using the
   * given prefix and suffix to generate its name. Invoking this method is
   * equivalent to invoking <code>{@link #createTempFile(java.lang.String,
   * java.lang.String, java.io.File)
   * createTempFile(prefix,&nbsp;suffix,&nbsp;null)}</code>.
   * 
   * @param prefix
   *          The prefix string to be used in generating the file's name; must
   *          be at least three characters long
   * @param suffix
   *          The suffix string to be used in generating the file's name; may be
   *          <code>null</code>, in which case the suffix <code>".tmp"</code>
   *          will be used
   * @param rootDirectory
   *          The directory in which the file is to be created, or
   *          <code>null</code> if the default temporary-file directory is to
   *          be used
   * @return An abstract pathname denoting a newly-created empty file
   * @throws TechnicalIOException
   *           if an error occured
   * @see File#createTempFile(String, String)
   */
  private File createTempFile(String prefix, String suffix, File rootDirectory)
      throws TechnicalIOException
  {
    try {
      return File.createTempFile(prefix, suffix, rootDirectory);
    }
    catch (IOException e) {
      throw getExceptionManager().convertException(e);
    }

  }
}
